package com.itmck.config;

import org.apache.shiro.session.SessionListener;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.*;


/**
 * 太阳当空照，花儿对我笑
 * <p>
 * Create by M ChangKe 2022/9/6 16:32
 * <p>
 * shiro配置
 */
@Configuration
public class ShiroConfig {



    /**
     * Shiro三板斧第一步，配置拦截过滤链。
     *
     * @return 拦截过滤链
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {

        //创建过滤工厂bean
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //注入安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager());


        Map<String, Filter> filters=new HashMap<>();
        filters.put("jwt", new JWTAuthcFilter(false));
        shiroFilterFactoryBean.setFilters(filters);

        /**
         * 添加shiro的内置过滤器：
         *
         *     anon: 无需认证就可访问
         *     authc：必须认证才能访问
         *     user：必须拥有记住我功能才能访问
         *     perms: 拥有对某个资源的权限才能访问
         *     role:拥有某个角色权限才能访问
         *
         *
         *     其中shiro提供了注解方式
         */
        //注意拦截链配置顺序 不能颠倒
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/login", "anon"); //登录页面
        filterChainDefinitionMap.put("/logout", "logout");//退出
        filterChainDefinitionMap.put("/unAuth", "anon");
        filterChainDefinitionMap.put("/user/login", "anon");

        filterChainDefinitionMap.put("/add", "perms[admin1]");

        filterChainDefinitionMap.put("/**", "authc");//拦截所有请求
        filterChainDefinitionMap.put("/**", "jwt");//拦截所有请求


        shiroFilterFactoryBean.setLoginUrl("/unAuth");//未认证 跳转未认证页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/unAuthor");//未授权 跳转未权限页面

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    /**
     * shiro三板斧第二步，配置域，用于subject的认证与授权操作
     *
     * @return Realm域
     */
    @Bean
    public CustomRealm customRealm(){
        CustomRealm customRealm = new CustomRealm();
//        customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return customRealm;
    }




    /**
     * shiro三板斧，第三步，配置shiro心脏 WebSecurityManager，
     *
     * @return WebSecurityManager
     */
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setSessionManager(sessionManager());
        manager.setCacheManager(redisCacheManager());
        manager.setRealm(customRealm());
        return manager;
    }


    @Bean
    public RedisCacheManager redisCacheManager(){
        RedisCacheManager cacheManager = new RedisCacheManager();
        return  cacheManager;
    }

    @Bean
    public DefaultWebSessionManager sessionManager(){
        CustomSessionManager sessionManager = new CustomSessionManager();
        List<SessionListener> list = new ArrayList<>();
        list.add(new MySessionListener());
        //sessionManager.setSessionValidationInterval(10000);
        sessionManager.setSessionListeners(list);
        sessionManager.setGlobalSessionTimeout(10000);
        sessionManager.setSessionDAO(redisSessionDao());
        return  sessionManager;
    }

    @Bean
    public RedisSessionDao redisSessionDao(){
        RedisSessionDao sessionDao = new RedisSessionDao();
        return sessionDao;
    }

//    @Bean
//    public HashedCredentialsMatcher hashedCredentialsMatcher(){
//        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//        matcher.setHashAlgorithmName("md5");
//        matcher.setHashIterations(1);
//        return matcher;
//    }

}
